package model

import (
	"bytes"
	"common/helper"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/valyala/fasthttp"
	"io/ioutil"
	"net/http"
	"sort"
	"strconv"
	"strings"
)

type BetCatPay struct {
}

func BetCatPaySign(data map[string]interface{}, key string) string {
	keys := []string{}
	for k := range data {
		keys = append(keys, k)
	}
	//排序
	sort.Strings(keys)

	//拼接字符串
	unsignStr := ""
	for _, v := range keys {

		value := ""
		switch data[v].(type) {
		case int:
			fmt.Println(data[v])
			value = fmt.Sprintf("%d", data[v].(int))
		case int32:
			value = fmt.Sprintf("%d", data[v].(int32))
		case int64:
			value = fmt.Sprintf("%d", data[v].(int64))
		case string:
			value = data[v].(string)
		case float32:
			value = strconv.FormatFloat(float64(data[v].(float32)), 'f', -1, 32)
		case float64:
			value = strconv.FormatFloat(data[v].(float64), 'f', -1, 64)
		default:

		}

		if v == "sign" || value == "" || v == "extends" || v == "error_info" {
			continue
		}
		if unsignStr == "" {
			unsignStr = v + "=" + value
		} else {
			unsignStr = unsignStr + "&" + v + "=" + value
		}
	}
	unsignStr = unsignStr + "&key=" + key
	return unsignStr
}

func withdrawBetCatPayOrder(iamount float64, PixAccount, uid, pixId, pixType, orderId string, pay TblPayFactory, RealName string) (withdrawResp, error) {

	var data withdrawResp

	requestURI := fmt.Sprintf("%s", pay.Url+"/api/v1/payout/order/create")

	if pixType == "PHONE" {
		if strings.HasPrefix(pixId, "55") {
			pixId = "+" + pixId
		} else {
			pixId = "+55" + pixId
		}

	}
	amount := fmt.Sprintf("%.2f", iamount)
	recs := map[string]interface{}{
		"appId":      pay.AppId,
		"merOrderNo": orderId,
		"currency":   "BRL",
		"amount":     amount, // 如 "12.34"
		"notifyUrl":  pay.NotifyUrl,
		"extra": map[string]interface{}{
			"bankCode":    pixType,
			"accountNo":   pixId,
			"accountName": RealName,
			"document":    PixAccount,
		},
	}
	content := fmt.Sprintf(`amount=%s&appId=%s&currency=%s&extra=accountName=%s&accountNo=%s&bankCode=%s&document=%s&merOrderNo=%s&notifyUrl=%s&key=%s`, amount, pay.AppId, "BRL", RealName, pixId, pixType, PixAccount, orderId, pay.NotifyUrl, pay.AppKey)
	//content := CepaySign(recs, pay.AppKey)

	// Step 1: 转成 UTF-8 字节数组（Go 字符串本身就是 UTF-8）
	byteData := []byte(content)
	// Step 2: SHA256 编码
	hash := sha256.Sum256(byteData)
	// Step 3: 转成 16 进制字符串
	sign := hex.EncodeToString(hash[:])

	recs["sign"] = sign
	helper.InfoLog("订单号%s，提交三方的参数：%s", orderId, content)

	requestBody, err := helper.JsonMarshal(recs)
	if err != nil {
		fmt.Println(err)
		return data, errors.New("参数错误")
	}
	fmt.Println(requestURI)
	fmt.Println(string(requestBody))
	client := &http.Client{}
	req, err := http.NewRequest("POST", requestURI, bytes.NewReader(requestBody))

	if err != nil {

		return data, errors.New(helper.PayServerErr)
	}
	req.Header.Add("Content-Type", "application/json")

	res, err := client.Do(req)
	fmt.Println(err)
	if err != nil {

		return data, errors.New(helper.PayServerErr)
	}
	defer res.Body.Close()

	body, err := ioutil.ReadAll(res.Body)
	helper.InfoLog("订单号%s，提交三方返回信息：%s", orderId, string(body))
	if err != nil {
		return data, errors.New(helper.PayServerErr)
	}

	if err != nil {
		return data, fmt.Errorf(helper.PayServerErr)
	}

	var retData = map[string]interface{}{}
	err = json.Unmarshal(body, &retData)
	if err != nil {
		return data, fmt.Errorf(helper.PayServerErr)
	}
	if _, ok := retData["code"]; ok {
		if _, ok = retData["error"]; ok {
			if retData["code"].(float64) == 400 {
				data.OrdStatus = "08"
			}
		}
	}
	return data, nil
}

func BetCatPayWithdrawCheckOrder(merchantOrderId, order string, pay TblPayFactory) (EpayCheckBack, error) {

	var data EpayCheckBack

	requestURI := fmt.Sprintf("%s", pay.Url+"/api/v1/payout/order/query")

	recs := map[string]interface{}{
		"appId":      pay.AppId,
		"merOrderNo": merchantOrderId,
	}

	content := fmt.Sprintf(`appId=%s&merOrderNo=%s&key=%s`, pay.AppId, merchantOrderId, pay.AppKey)
	//content := CepaySign(recs, pay.AppKey)

	// Step 1: 转成 UTF-8 字节数组（Go 字符串本身就是 UTF-8）
	byteData := []byte(content)
	// Step 2: SHA256 编码
	hash := sha256.Sum256(byteData)
	// Step 3: 转成 16 进制字符串
	sign := hex.EncodeToString(hash[:])

	recs["sign"] = sign

	requestBody, err := helper.JsonMarshal(recs)
	fmt.Println(string(requestBody))
	if err != nil {
		return data, errors.New("参数错误")
	}

	client := &http.Client{}
	requestURI += "?appId=" + pay.AppId + "&merOrderNo=" + merchantOrderId + "&sign=" + sign
	req, err := http.NewRequest("GET", requestURI, bytes.NewReader([]byte{}))

	if err != nil {
		return data, errors.New(helper.PayServerErr)
	}
	//req.Header.Add("Content-Type", "application/json")

	res, err := client.Do(req)
	fmt.Println(err)
	if err != nil {

		return data, errors.New(helper.PayServerErr)
	}
	defer res.Body.Close()

	body, err := ioutil.ReadAll(res.Body)
	helper.InfoLog("订单号%s，审核三方返回信息：%s", merchantOrderId, string(body))
	if err != nil {
		return data, errors.New(helper.PayServerErr)
	}

	var retData = map[string]interface{}{}
	err = json.Unmarshal(body, &retData)

	if err != nil {
		return data, fmt.Errorf(helper.PayServerErr)
	}
	data.Code = "0"
	if _, ok := retData["code"]; ok {
		if _, ok = retData["error"]; ok {
			if retData["code"].(float64) == 400 && retData["error"].(string) == "订单不存在" {
				data.Code = "-1"
			}
		}
	}

	return data, nil
}

func (that *BetCatPay) WithdrawBetCatPayCallBack(fctx *fasthttp.RequestCtx) (paymentCallbackResp, error) {
	returnData := paymentCallbackResp{}

	var postData1 = map[string]interface{}{}
	err := json.Unmarshal(fctx.PostBody(), &postData1)
	if err != nil {
		return returnData, err
	}

	postData2 := postData1
	orderId := postData2["merOrderNo"].(string)

	query := "select * from tbl_withdraw where id='" + orderId + "'"
	order := tblWithdraw{}
	err = meta.MerchantDB.Get(&order, query)
	if err != nil {
		return returnData, err
	}
	keyy := ""
	query = "select app_key from tbl_pay_factory where fid=" + order.FID
	err = meta.MerchantDB.Get(&keyy, query)
	if err != nil {
		return returnData, err
	}

	content := BetCatPaySign(postData2, keyy)

	// Step 1: 转成 UTF-8 字节数组（Go 字符串本身就是 UTF-8）
	byteData := []byte(content)
	// Step 2: SHA256 编码
	hash := sha256.Sum256(byteData)
	// Step 3: 转成 16 进制字符串
	sign := hex.EncodeToString(hash[:])
	oldSign := postData1["sign"].(string)

	if oldSign != sign {
		fmt.Printf("old sign=%s, new state=%s", oldSign, sign)
		helper.InfoLog("%s订单号签名不对", orderId, content)
		return returnData, errors.New(helper.SignValidErr)
	}
	returnData.MerchantOrderId = orderId
	//成功
	if _, ok := postData2["orderStatus"]; ok {
		if postData2["orderStatus"].(float64) == 2 || postData2["orderStatus"].(float64) == 3 {
			returnData.OrderStatus = "07"
		}
		//失败 或 关闭
		if postData2["orderStatus"].(float64) == -1 || postData2["orderStatus"].(float64) == -2 || postData2["orderStatus"].(float64) == -3 {
			returnData.OrderStatus = "08"
		}
	}

	return returnData, nil
}
